package com.ls.fw.mvc.springmvc.test;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ls.fw.commons.core.utils.collections.CollectionUtils;
import com.ls.fw.data.bean.PageBean;
import com.ls.fw.data.bean.ResultStatus;
import com.ls.fw.data.bean.ResultTemplate;
import com.ls.fw.data.result.ErrorResult;
import com.ls.fw.mvc.springmvc.base.BaseCRUDController;
import com.ls.fw.mvc.springmvc.support.annotation.RequestProtocol;
import com.ls.fw.mvc.springmvc.support.arg.form.FormModel;
import com.ls.fw.mvc.springmvc.support.arg.form.MapWapper;
import com.ls.fw.mvc.springmvc.test.model.SysUserAccount;
import com.ls.fw.mvc.springmvc.test.service.SysUserAccountService;
import com.ls.fw.mvc.springmvc.test.vo.SysUserAccountVo;
import com.ls.fw.mvc.springmvc.util.ViewUtil;
import com.ls.fw.web.core.servlet.utils.UrlUtils;

/** 
 * 
 * @author ls
 */
@Controller
@RequestMapping(value = "${adminPath}/test")
public class MyTestController extends BaseCRUDController
{
  
  
    @Autowired
	private SysUserAccountService testService;
 
    //http://127.0.0.1/backend-mvc-springmvc-test/test/form
    @RequestProtocol(secure=true)
    @RequestMapping("/form")
	public ModelAndView form(WebRequest webRequest,
			@FormModel("list") List<SysUserAccount> list
			,@FormModel("map") MapWapper<String, Integer> map){
		System.out.println(list);
		System.out.println(map);
		return ViewUtil.convert(this.returnResult(ResultTemplate.newInstance()), webRequest);
	}
    //http://127.0.0.1/backend-mvc-springmvc-test/test/form1?_json=1&student.name=1&student1.name=2
    @RequestMapping("/form1")
   	public ModelAndView form1(WebRequest webRequest, @FormModel("student") SysUserAccount student,@FormModel("student1") SysUserAccount student1){
   		System.out.println(student);
   		System.out.println(student1);
   		return ViewUtil.convert(this.returnResult(ResultTemplate.newInstance()), webRequest, CollectionUtils.<String>newSet()
   				,CollectionUtils.<String>newSet("student","student1"));
   	}
    @RequestMapping("/saverdd")
    public String saverdd(String name,String msg, ModelMap attr)
                   throws Exception {
    	System.out.println(attr);
        attr.addAttribute("name", name);  
        attr.addAttribute("msg", msg);
        return "/test/form";
    }
    @RequestMapping("/saver")
    public String saver(@ModelAttribute("form") SysUserAccount form,String code, RedirectAttributes attr, HttpServletRequest request)
                   throws Exception {
    	System.out.println(UrlUtils.buildFullRequestUrl(request));;
        if(code.equals("000")){
            attr.addFlashAttribute("name", form.getName());  
            attr.addFlashAttribute("msg", "添加成功!");
            return "redirect:/test/saverdd";
        }else{
        	//传递参数会跟随在URL后面，如上代码即为http:/test/saverdd?name=name
            attr.addAttribute("name", form.getName());  
            //不会跟随在URL后面，会把该参数值暂时保存于session，待重定向url获取该参数后从session中移除，这里的redirect必须是方法映射路径，jsp无效。
            //你会发现redirect后的jsp页面中b只会出现一次，刷新后b再也不会出现了，这验证了上面说的，b被访问后就会从session中移除。
            //对于重复提交可以使用此来完成.
            attr.addFlashAttribute("msg", "添加出错!错误码为");
            return "redirect:/test/saverdd";
        }
    }
    @RequestMapping("/index")
    public String index(HttpServletRequest req) {
      
        return "/test/index";
    } 
    
    
    @RequestMapping(value = "/"+DELETE)
	public ModelAndView delete(WebRequest webRequest, @RequestParam(required=true ) String ids) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doDelete(ids, webRequest, this.viewPrefix+mapping
		,  new DeleteWorkHandler() {

			@Override
			public ResultTemplate doWork(String[] ids, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				try {
					testService.delete(ids);
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}

    @RequestMapping(value = "/"+REMOVE)
	public ModelAndView remove(WebRequest webRequest, @RequestParam(required=true ) String ids) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doDelete(ids, webRequest, this.viewPrefix+mapping
		, new DeleteWorkHandler() {

			@Override
			public ResultTemplate doWork(String[] ids, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				try {
					testService.remove(ids);
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}

    @RequestMapping(value = "/"+ADD)
	public ModelAndView add(WebRequest webRequest, @Validated SysUserAccountVo vo
                          , final BeanPropertyBindingResult result) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doSave(vo, webRequest, this.viewPrefix+mapping
             , new SaveWorkHandler<SysUserAccountVo>() {

			@Override
			public ResultTemplate doWork(SysUserAccountVo vo, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				if(result.hasErrors()){
					obj.setData(ErrorResult.from(result));
					obj.setStatus(ResultStatus.BAD_REQUEST);
				}else{
					try {
						SysUserAccount model = new SysUserAccount();
				    	BeanUtils.copyProperties(vo, model);
						testService.save(model);
						obj.setData(model);
						obj.setStatus(ResultStatus.OK);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						obj.setMsg(e.getMessage());
					}
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/to"+ADD)
	public ModelAndView toAdd(WebRequest webRequest) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doTo("", webRequest, this.viewPrefix+mapping
             ,  new ToWorkHandler() {

			@Override
			public ResultTemplate doWork(String id, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				try {
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/"+UPDATE)
	public ModelAndView update(WebRequest webRequest, @Validated SysUserAccountVo vo
	                         , final BeanPropertyBindingResult result) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doSave(vo, webRequest, this.viewPrefix+mapping
             ,  new SaveWorkHandler<SysUserAccountVo>() {

			@Override
			public ResultTemplate doWork(SysUserAccountVo vo, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				if(result.hasErrors()){
					obj.setData(ErrorResult.from(result));
					obj.setStatus(ResultStatus.BAD_REQUEST);
				}else{
					try {
						SysUserAccount model = new SysUserAccount();
				    	BeanUtils.copyProperties(vo, model);
						testService.update(model);
						obj.setData(model);
						obj.setStatus(ResultStatus.OK);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						obj.setMsg(e.getMessage());
					}
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/to"+UPDATE)
	public ModelAndView toUpdate(WebRequest webRequest, @RequestParam(required=true ) String id) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doTo(id, webRequest, this.viewPrefix+mapping
             ,  new ToWorkHandler() {

			@Override
			public ResultTemplate doWork(String id, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				try {
					SysUserAccount data = testService.find(Long.parseLong(id));
					obj.setData(data);
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/"+SAVE)
	public ModelAndView save(WebRequest webRequest, @Validated SysUserAccountVo vo
	                       , final BeanPropertyBindingResult result) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doSave(vo, webRequest, this.viewPrefix+mapping
		     ,  new SaveWorkHandler<SysUserAccountVo>() {

			@Override
			public ResultTemplate doWork(SysUserAccountVo vo, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				if(result.hasErrors()){
					obj.setData(ErrorResult.from(result));
					obj.setStatus(ResultStatus.BAD_REQUEST);
				}else{
					try {
						SysUserAccount model = new SysUserAccount();
				    	BeanUtils.copyProperties(vo, model);
						testService.persist(model);
						obj.setData(model);
						obj.setStatus(ResultStatus.OK);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						obj.setMsg(e.getMessage());
					}
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/to"+EDIT)
	public ModelAndView toEdit(WebRequest webRequest, @RequestParam(required=true ) String id) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doTo(id, webRequest, this.viewPrefix+mapping
		     ,  new ToWorkHandler() {

			@Override
			public ResultTemplate doWork(String id, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				try {
					SysUserAccount data = testService.find(Long.parseLong(id));
					obj.setData(data);
					obj.setStatus(ResultStatus.OK);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
					obj.setMsg(e.getMessage());
				}
				return obj;
			}
		});
	}


    @RequestMapping(value = "/"+QUERY)
	public ModelAndView query(WebRequest webRequest, boolean noPage 
	                        ,@RequestParam(value="page",required=false,defaultValue="1") Integer page
	                        ,@RequestParam(value="pageSize",required=false,defaultValue="10") Integer pageSize
	                        , @Validated SysUserAccountVo q,final BeanPropertyBindingResult result) throws Exception {
    	String method = Thread.currentThread() .getStackTrace()[1].getMethodName();
    	String mapping = this.methodRequestMapping.get(method);
		return this.doQuery(noPage, page, pageSize, q, webRequest
		     , this.viewPrefix+mapping
		     , new QueryWorkHandler<SysUserAccountVo>() {

			@Override
			public ResultTemplate doWork(boolean noPage, Integer page,
					Integer pageSize, SysUserAccountVo q, WebRequest webRequest)
					throws Exception {
				ResultTemplate obj = ResultTemplate.newInstance();
				//TODO:调用service
				if(result.hasErrors()){
					obj.setData(ErrorResult.from(result));
					obj.setStatus(ResultStatus.BAD_REQUEST);
				}else{
					try {
						 if(!noPage){
			                if(page==null){
			                    page = PageBean.PAGE;
			                }
			                if(pageSize==null){
			                    pageSize = PageBean.PAGE_SIZE;
			                }
//			                PageHelper.startPage(page,pageSize); 
			            }
						List list = testService.query(q);
						obj.setData(new PageBean(list));
						obj.setStatus(ResultStatus.OK);
					} catch (Exception e) {
						logger.error(e.getMessage(), e);
						obj.setMsg(e.getMessage());
					}
				}
				return obj;
			}
		});
	}
}
